package com.example.check.validator;

import cn.hutool.core.bean.BeanUtil;
import com.example.check.ConditionJointOnly;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * @author zhazha
 * @date 2021/7/8
 */
@Slf4j
public class ConditionJointOnlyValidator
        implements ConstraintValidator<ConditionJointOnly, Object> {

    /**
     * 不为空
     */
    public static final String NOT_BLACK = "notBlack";

    /**
     * 条件属性名字
     */
    private String conditionName;
    /**
     * 结果属性名字
     */
    private String resultName;
    /**
     * 条件属性值
     */
    private String conditionValue;
    /**
     * 结果属性值
     */
    private Set<String> resultValueSet;

    /**获取注解中声明的属性
     * TODO 可以简化为其他只有2个属性
     *      绑定的属性，以及消息。默认值可以用default替代
     *      例如	String value() default "";
     * */
    @Override
    public void initialize(@NotNull ConditionJointOnly conditionResult) {
        this.conditionName = conditionResult.conditionName();
        this.resultName = conditionResult.resultName();

        this.conditionValue = conditionResult.conditionValue();
        this.resultValueSet = new HashSet<>(Arrays.asList(conditionResult.resultValue()));
    }

    /**放在类上面就是Obj?*/
    @Override
    public boolean isValid(Object obj, ConstraintValidatorContext context) {

        // key为空或者value 为空
        if (StringUtils.hasText(this.conditionName)
                || StringUtils.hasText(this.resultName)
                || StringUtils.hasText(this.conditionValue)
                || CollectionUtils.isEmpty(this.resultValueSet)) {
            return false;
        }
        final String resultFieldValue;

        //转化出现异常直接返回false
        try {
            /*获取条件属性值*/
            final String conditionFieldValue =
                    BeanUtil.getProperty(obj, this.conditionName);
            // 条件不成立，则此约束不进入
            if (!Objects.equals(this.conditionValue, conditionFieldValue)) {
                return true;
            }
            // 条件进入，则会进入此校验结果的字符串
            resultFieldValue = BeanUtil.getProperty(
                    obj, this.resultName);
        } catch (Exception e) {
            log.error("数据校验时出现未知异常，具体异常：{}",e.toString());
            return false;
        }

        //预期如果是字符串不为空，则校验
        if (this.resultValueSet.contains(NOT_BLACK)) {
            return StringUtils.hasText(resultFieldValue);
        } else {
            //预期的结果集与实际是否符合
            return this.resultValueSet.contains(resultFieldValue);
        }

    }
}